using System.Reflection;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;

namespace RSCore;

public class HookManager : IDisposable
{
	private static HookManager? _shared;

	public static HookManager Shared => _shared ??= new HookManager();

	private List<IDisposable> hooks = new();

	public void AddHook(MethodBase method, Delegate hook) => hooks.Add(new Hook(method, hook));

	public void AddHook(MethodBase method, ILContext.Manipulator manipulator) => hooks.Add(new ILHook(method, manipulator));

	public void ClearHook()
	{
		foreach (var hook in hooks)
		{
			hook.Dispose();
		}
		hooks.Clear();
		ClearMonoModCache();
	}

	public static void ClearMonoModCache()
	{
		ReflectionHelper.AssemblyCache.Clear();
		ReflectionHelper.AssembliesCache.Clear();
		ReflectionHelper.ResolveReflectionCache.Clear();
	}

	public void Dispose()
	{
		ClearHook();
		GC.SuppressFinalize(this);
	}
}